#include <iostream>

using std::cout;
using std::endl;

//当使用base *=deriver时，
//则在deriver对象的base范围里搜索，如果有重写的虚函数，base范围里也是看得到的
//如果没有，则只能看见base的函数，永远停留在base里
class Base{
public:
    Base()
    : _base(0)
    {
        cout<<"Base()"<<endl;
    }
    Base(long base)
    : _base(base)
    {
        cout<<"Base(long)"<<endl;
    }
    ~Base(){
        cout<<"~Base()"<<endl;
    }

    void show() const{
        cout<<"Base::show()"<<endl;
    }

private:
    long _base;
};

class Deriver
: public Base
{
public:
    Deriver()
    : Base()
    , _deriver(0)
    {
        cout<<"Deriver()"<<endl;
    }
    Deriver(long base, long deriver)
    : Base(base)
    , _deriver(deriver)
    {
        cout<<"Deriver(long,long)"<<endl;
    }
    ~Deriver(){
        cout<<"~Deriver()"<<endl;
    }

    void print() const{
        cout<<"Deriver::print()"<<endl;
    }

    void show() const{
        cout<<"Deriver::show()"<<endl;
    }

private:
    long _deriver;
};

void test(){
    //向上转型
    Base base(100);
    base.show();

    cout<<endl;
    Deriver derived(111,222);
    derived.print();
    derived.show();
    derived.Base::show();
    
    cout<<endl<<"从派生类对象向基类对象转换"<<endl;
    base=derived;   //派生类对象赋值给基类对象
    //此时调用赋值运算符函数 Base &operator=(const Base &rhs)
    //  形参实参结合，const Base &rhs = derived
    //  即基类引用绑定到派生类对象
    base.show();

    cout<<endl;
    Base &ref=derived;
    ref.show();

    //引用的底层实现就是指针，所以基类指针可以指向派生类对象
    cout<<endl;
    Base *pbase=&derived;
    pbase->show();
    //调用的是Base的show，说明这样指向之后，已经和deriver没有关系
//    pbase->print();没有
}

void test2(){
    //向下转型，往往不安全
    Base base(22);
    base.show();
    Deriver derived(1000,2000);
    derived.print();
    derived.show();
    
    cout<<endl<<"不能用基类对象给派生类对象赋值"<<endl;
    //derived=base;
    //此时调用赋值运算符函数 Deriver &operator=(const Deriver &rhs)
    //  &rhs = base
    //  即派生类引用不能绑定到基类对象

    //Deriver &ref=base;

    //引用的底层实现就是指针，所以派生类指针不可以指向基类对象
    //比如派生类的size是16，那么它的指针操作范围就是16，如果此时指向base
    //那么会超过8节点操作范围，有越界风险
    //Deriver *p = &base;
    Deriver *p = static_cast<Deriver *>(&base); 
    //不安全。可以pbase指向派生，再让派生指针指向pbase，多此一举

}
int main()
{   
    test();
    return 0;
}

